# 函数定义
# def my_abs (n):
    # if n>=0:
        # return n
    # return -n
    
# print(my_abs(12))
# print(my_abs(-24))

# def nop():
    # pass
# age = 30
# if age >= 18:
    # pass

# nop()

# abs('a')
# my_abs('a')

# def my_abs (n):
    # if not isinstance(n,(int,float)):
        # raise TypeError('传入的数据类型不对！')
    # if n>=0:
        # return n
    # return -n

# my_abs('a')

# import math
# def move (x,y,step,angle=0):
    # nx = x + step*math.cos(angle)
    # #往下为正方向
    # ny = y - step*math.sin(angle)
    # return nx,ny

# x,y = move(100,100,60,math.pi/6)
# print(x,y)

# res = move(100,100,60,math.pi/6)
# print(res)

# 求x的n次方
# def power(x,n):
    # s = 1
    # while n>0:
        # s *= x
        # n -= 1
    # return s
# print(power(15,2))
# print(power(2,10))

# def power(x,n=2):
    # s = 1
    # while n>0:
        # s *= x
        # n -= 1
    # return s
# print(power(6))
# print(power(5,3))

# def enroll(name,grade,age=7,city='青岛'):
    # # print('name: ',name)
    # # print('grade: ',grade)
    # # print('age: ',age)
    # # print('city: ',city)
    # print('%d岁的%s，在%s上%s' % (age,name,city,grade))
    
# enroll('倪萍','一年级')
# enroll('吕思清','三年级',9)
# enroll('关中刀客','四年级',10,'宝鸡')
# enroll('关中刀客','一年级',city='宝鸡')

# def and_end(L=[]):
    # L.append('end')
    # return L

# print(and_end(['小宝']))
# print(and_end(['阿宝']))

# print(and_end())
# print(and_end())

# def and_end(L=None):
    # # 这里也可写成 L == None
    # if L is None:
        # L = []
    # L.append('end')
    # return L

# print(and_end(['小宝']))
# print(and_end(['阿宝']))

# print(and_end())
# print(and_end())

# 定义一个求平方和的函数，使用可变参数
# def calc(*nums):
    # sum = 0
    # for num in nums:
        # sum += num * num
    # return sum
# print(calc(1,2,3))
# print(calc())
# print(calc(*[1,2,3,4]))
# print(calc(*(1,2,3,4)))

# 关键字参数
# def cars(age,color,**kw):
    # functions = ''
    # material = ''
    # for k in kw:
        # if k == 'material':
            # material = kw[k]
        # else:
            # functions += kw[k]+'、'
    # # python没有三目运算符，这种写法还不习惯
    # return '用了%d年的%s小%s车，还有%s的功能' % (age,material,color,functions[:-1] if len(functions)>0 else '等你研究')

# print(cars(3,'黄'))
# print(cars(1,'白',func1='自己跑',material='塑料'))
# print(cars(2,'蓝',material='金属',said='自己跑',has='会唱歌',func3='讲故事'))
# # 对象的字面量写法中，key不能省略引号
# # 关键字参数传入到函数时，会被复制一份再组装成dict传给kw，所以对kw的改变不会影响到fncts
# funcs = {'material':'以太','said':'自己和自己玩','has':'会72变','and':'带你学习'}
# print(cars(2,'蓝',**funcs))

# 命名关键字参数
# propertyAndFlavor-性味；meridian-归经
# def logTCM(name,efficacy, *,propertyAndFlavor='未知',meridian='？',classes='待定'):
    # print('%s，功效是%s，性味%s，归%s经，分类为%s' % (name,efficacy,propertyAndFlavor,meridian,classes))

# logTCM('月季花','活血调经,消肿')
# logTCM('辛夷','散风寒,通鼻窍',propertyAndFlavor='辛温')
# logTCM('南瓜子','杀虫',propertyAndFlavor='甘平',meridian='胃、大肠',classes='驱虫药')
# logTCM('大黄','泻下攻积，清热泻火',daoDanGui='我来捣蛋')

# 参数组合
# def f1(a,b,c=0,*args,**kw):
    # print('~f1','a=',a,'b=',b,'c=',c,'args=',args,'kw=',kw)
# def f2(a,b,c=0,*,d,**kw):
    # print('~f2','a=',a,'b=',b,'c=',c,'d=',d,'kw=',kw)
# f1(1,2)
# f1(1,2,c=3)
# f1(1,2,3,'a','b')
# f1(1,2,3,'a','b',x=818)
# f2(1,2,3,d='DD',x=919)
# f2(1,2,3,d='DD',daoDanGui='我来捣蛋',x=919)

# args = (1,2,3,4)
# kw={'d':'818','x':'XX'}
# f1(*args,**kw)
# args = (1,2,3)
# kw={'d':'919','x':'XX2'}
# f2(*args,**kw)

# # 可接收一个或多个数并计算乘积
# def mul(*args):
    # if len(args) == 0:
        # # 如果没有参数，抛出错误
        # raise TypeError
    # s = 1
    # for arg in args:
        # s *= arg
    # return s

# 递归函数
def fact(n):
    if n==1: 
        return 1
    return n * fact(n-1)
    
print(fact(6))
print(fact(1000))

# 改为尾递归优化
def fact(n,r):
    if n<=0:
        return r
    return fact(n-1, n*r)
print(fact(6,1))
print(fact(1000,1))
